﻿//*****************************************************************************
//
//  Silver Games - Checkers
//  Copyright © 2009 Randi Relander
//      <rjrelander@users.sourceforge.net>
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//*****************************************************************************

using System;

namespace Checkers.Common
{
    public class Game
    {
        public enum Winner
        {
            Draw,
            Red,
            Black
        };

        public class GameOverEventArgs : EventArgs
        {
            public Winner Winner { get; set; }
        }

        public delegate void GameOverEventHandler(object sender, GameOverEventArgs e);

        public event GameOverEventHandler GameOverEvent;

        public Game()
        {
            mPlayers[0] = new Player(CheckerColor.Red);
            mPlayers[1] = new Player(CheckerColor.Black);

            mPlayers[0].Next = mPlayers[1];
            mPlayers[1].Next = mPlayers[0];

            SetStartTiles();

            CurrentPlayer = mPlayers[0];
        }

        private void SetStartTiles()
        {
            GetChecker(0, 0).StartTile = GetTile(0, 0);
            GetChecker(0, 1).StartTile = GetTile(2, 0);
            GetChecker(0, 2).StartTile = GetTile(4, 0);
            GetChecker(0, 3).StartTile = GetTile(6, 0);
            GetChecker(0, 4).StartTile = GetTile(1, 1);
            GetChecker(0, 5).StartTile = GetTile(3, 1);
            GetChecker(0, 6).StartTile = GetTile(5, 1);
            GetChecker(0, 7).StartTile = GetTile(7, 1);
            GetChecker(0, 8).StartTile = GetTile(0, 2);
            GetChecker(0, 9).StartTile = GetTile(2, 2);
            GetChecker(0, 10).StartTile = GetTile(4, 2);
            GetChecker(0, 11).StartTile = GetTile(6, 2);

            GetChecker(1, 0).StartTile = GetTile(7, 7);
            GetChecker(1, 1).StartTile = GetTile(5, 7);
            GetChecker(1, 2).StartTile = GetTile(3, 7);
            GetChecker(1, 3).StartTile = GetTile(1, 7);
            GetChecker(1, 4).StartTile = GetTile(6, 6);
            GetChecker(1, 5).StartTile = GetTile(4, 6);
            GetChecker(1, 6).StartTile = GetTile(2, 6);
            GetChecker(1, 7).StartTile = GetTile(0, 6);
            GetChecker(1, 8).StartTile = GetTile(7, 5);
            GetChecker(1, 9).StartTile = GetTile(5, 5);
            GetChecker(1, 10).StartTile = GetTile(3, 5);
            GetChecker(1, 11).StartTile = GetTile(1, 5);
        }

        Player[] mPlayers = new Player[2];

        Board mBoard = new Board();

        public Board Board { get { return mBoard; } }

        public Player CurrentPlayer { get; set; }

        public Player GetPlayer(int n)
        {
            if ((n < 0) || (n >= 2)) return null;
            return mPlayers[n];
        }

        public Tile GetTile(int x, int y)
        {
            return mBoard.GetTile(x, y);
        }

        public Checker GetChecker(int playerIndex, int checkerIndex)
        {
            Player player = GetPlayer(playerIndex);
            if (player == null) return null;
            return player.GetChecker(checkerIndex);
        }

        public void Reset()
        {
            foreach (Player player in mPlayers)
            {
                player.RemovePieces();
            }

            foreach (Player player in mPlayers)
            {
                player.Reset();
            }

            CurrentPlayer = mPlayers[0];

            CurrentPlayer.StartTurn();
        }

        public void NextPlayer()
        {
            CurrentPlayer.EndTurn();

            CurrentPlayer = CurrentPlayer.Next;
            
            CurrentPlayer.StartTurn();

            if (CurrentPlayer.MoveList.Count == 0)
            {
                if (GameOverEvent != null)
                {
                    GameOverEventArgs eventArgs = new GameOverEventArgs();

                    if (CurrentPlayer.Color == CheckerColor.Red)
                        eventArgs.Winner = Winner.Black;
                    else eventArgs.Winner = Winner.Red;

                    GameOverEvent(this, eventArgs);
                }
            }
        }
    }
}
